﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services.FinancialServices;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class UnionDepositAssociationViewModel : IViewModel
    {
        /// <summary>
        /// 
        /// </summary>
        IAdministrationRepository _AdministrationRepository;
        /// <summary>
        /// 
        /// </summary>
        IFinanceService _FinanceService;

        /// <summary>
        /// Initializes a new instance of the <see cref="UnionDepositAssociationViewModel"/> class.
        /// </summary>
        /// <param name="administrationRepository">The administration repository.</param>
        /// <param name="financeService">The finance service.</param>
        public UnionDepositAssociationViewModel(IAdministrationRepository administrationRepository, IFinanceService financeService)
        {
            _AdministrationRepository = administrationRepository;
            _FinanceService = financeService;
        }


        /// <summary>
        /// Gets all committees.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ICommittee> GetAllCommittees()
        {
            return _AdministrationRepository.GetAllCommittees();
        }

        /// <summary>
        /// Gets all committees.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ICommittee> GetAllNonMainCommittees()
        {
            return _AdministrationRepository.GetAllCommittees();
        }

        /// <summary>
        /// Gets the main committee balance.
        /// </summary>
        /// <returns></returns>
        public double GetMainCommitteeBalance()
        {
            return _FinanceService.GetMainCommitteeBalance();
        }

        /// <summary>
        /// Gets the main association deposits.
        /// </summary>
        /// <param name="committeeID">The committee ID.</param>
        /// <returns></returns>
        public IEnumerable GetMainAssociationDeposits(Guid committeeID)
        {
            var committee = _AdministrationRepository.GetCommitteeByID(committeeID);
            var committeeDeposites = committee.CommitteeBankAccounts.SelectMany(bankAccount => bankAccount.CommitteeBankAccountMainBranchDeposites).OrderBy(cbambDeposit => cbambDeposit.DepositDate);

            return from deposit in committeeDeposites
                   select new
                   {
                       DepositDate = deposit.DepositDate,
                       DepositAmount = deposit.DepositAmount,
                       OperationNumber = deposit.OperationNumber,
                       ProjectName = deposit.CommitteeBankAccount.Project.ProjectName
                   };
        }

        /// <summary>
        /// Deposits the committee.
        /// </summary>
        /// <param name="committeeID">The committee ID.</param>
        /// <param name="projectID">The project ID.</param>
        /// <param name="depositAmount">The deposit amount.</param>
        /// <param name="depositDate">The deposit date.</param>
        /// <param name="operationNumber">The operation number.</param>
        /// <param name="insertedAttachmentIDs">The inserted attachment I ds.</param>
        /// <param name="deletedAttachmentIDs">The deleted attachment I ds.</param>
        public void DepositCommittee(Guid committeeID, Guid projectID, double depositAmount, DateTime depositDate
            , string operationNumber, IEnumerable<Guid> insertedAttachmentIDs, IEnumerable<Guid> deletedAttachmentIDs)
        {
            using (IUnitOfWork trans = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                var bankAccount =
                    _AdministrationRepository.FindCommitteeBankAccounts(
                        commBA => commBA.CommitteeID.Equals(committeeID) &&
                                  commBA.ProjectID.Equals(projectID)).FirstOrDefault();

                if (bankAccount != null)
                {
                    Guid unionDepositID = _FinanceService.UnionDepositCommittee(depositAmount, committeeID, operationNumber,
                        bankAccount.CommitteeBankAccountID, depositDate);

                    bankAccount.Balance = bankAccount.Balance.GetValueOrDefault(0) + depositAmount;

                    insertedAttachmentIDs.Where(attach => deletedAttachmentIDs.Contains(attach)).ForEach(
                        insertedID =>
                        {
                            ICommitteeBankAccountMainBranchDepositAttachment commUnionDepoAttach = ServiceLocator.Current.GetInstance<ICommitteeBankAccountMainBranchDepositAttachment>();
                            commUnionDepoAttach.CommitteeBankAccountMainBranchDepositAttachmentID = Guid.NewGuid();
                            commUnionDepoAttach.CommitteeBankAccountMainBranchDepositID = unionDepositID;
                            commUnionDepoAttach.Attachment = insertedID;
                            _AdministrationRepository.CreateCommitteeBankAccountMainBranchDepositAttachment(commUnionDepoAttach);
                        }
                    );

                    _AdministrationRepository.DeleteCommitteeBankAccountMainBranchDepositAttachments(
                        att => deletedAttachmentIDs.Contains(att.Attachment));

                    trans.Commit();
                }
            }

        }

        /// <summary>
        /// Gets the user project ID.
        /// </summary>
        /// <returns></returns>
        internal IEnumerable GetUserProjects()
        {
            return _AdministrationRepository.GetUserProjects(RegistryInfo.UserID);
        }
    }
}
